/**************************************************************************************
*  Bench.java
*  Simple benchmarking program.
**************************************************************************************
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL RTJ COMPUTING BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Created by:
*      RTJ Computing
**************************************************************************************/
import lpc2xxx.hw.*;

public class Bench {

    static final int NUM_BM_UNITS = 5;    // number of different benchmarks
    static final int BM_TIME = 100;      // duration of measurement [seconds]

    // standard Java (Sun) entry point:
    public static void main(String[] args) {
        int duration = BM_TIME;

        Console.println("\r\nSimple benchmark test.");
        Console.println("  Following benchmarks are performed:");
        Console.println("  1. Sieve");
        Console.println("  2. String");
        Console.println("  3. Method");
        Console.println("  4. Logic");
        Console.println("  5. Loop");
        Console.println("Benchmark duration: "+duration+" seconds");
        Console.println("Press ENTER key to start, ESC to quit now.\r\n");
        while (true)
        {
            char key = Console.getKey();
            if (key == Console.ESC)
                return;
            else if (key == Console.CR)
                break;
        }

        int unit = 0;
        Console.println("Starting benchmark");
        if (args.length > 0 && args[0] != null)
        {
            try
            {
                duration = Integer.parseInt(args[0]);
            }
            catch (NumberFormatException e)
            {
                Console.println("Invalid command line parameter \""+args[0]+"\"");
            }
        }

        // arrays for the benchmarks and the threads:
        BenchmarkUnit[] bmUnit = new BenchmarkUnit[NUM_BM_UNITS];
        Thread[] bmThread = new Thread[NUM_BM_UNITS];

        // init benchmarks:
        bmUnit[unit++] = new SieveBenchmarkUnit();
        bmUnit[unit++] = new StringBenchmarkUnit();
        bmUnit[unit++] = new MethodBenchmarkUnit();
        bmUnit[unit++] = new LogicBenchmarkUnit();
        bmUnit[unit++] = new LoopBenchmarkUnit();

        // make new Threads
        for (unit=0; unit < NUM_BM_UNITS; unit++)
            bmThread[unit] = new Thread(bmUnit[unit]);

        // start the threads:
        for (int i=0; i < NUM_BM_UNITS; i++) bmThread[i].start();
        // make this thread sleep:
        try {
            int sleepTime = duration * 100;
            for (int i=0; i < 10; i++) {
                Console.print(".");
                Thread.sleep(sleepTime);
            }
            Console.println("");
        } catch (InterruptedException iX) { /* ingore */ }

        // stop the threads:
        for (int i=0; i < NUM_BM_UNITS; i++) bmUnit[i].stopRunning();
        // threads & array no longer needed, can be garbage collected:
        bmThread = null;
        System.gc();

        // write out the scores:
        for (int i=0; i < NUM_BM_UNITS; i++) {
            Console.print( bmUnit[i].getName() + ": loops = " + bmUnit[i].getLoopCount() );
            Console.println(", errors = " +  bmUnit[i].getOutOfMemoryErrorCount() );
        }
    }
}
